let configuration = require('../../configuration');
let utils = require('../../utils');
let ComponentContainer = require('../ComponentContainer');
let Skill = require('./skill');
let Buff = require('./buff');

class LeftSideBar {
    constructor() {
        this.x = 0;
        this.y = 0;
        this.width = configuration.get('components.leftSideBar.width');
        this.height = configuration.get('window.height');

        this.selectedCard = null;
        this.activeCard = null;

        this.skillsContainer = new ComponentContainer();
        this.buffsContainer = new ComponentContainer();

        this.__load();
    }

    __load() {
        configuration.getImage('back', image => {
            this.back = image;
        });
        configuration.getImage('star', image => {
            this.starImage = image;
        });
    }

    init(initConfig) {
        let initConfig1 = utils.clone(initConfig);
        initConfig1.baseX = 0;
        initConfig1.baseY = this.height - configuration.get('components.skill.width') -
            configuration.get('components.leftSideBar.skillMarginBottom');
        this.skillsContainer.init(initConfig1);

        let initConfig2 = utils.clone(initConfig);
        initConfig2.baseX = 0;
        initConfig2.baseY = 0;
        this.buffsContainer.init(initConfig2);
    }

    includesPoint(x, y) {
        return x > this.x && x < this.x + this.width && y > this.y && y < this.y + this.height;
    }

    mousePos(x, y) {
        this.skillsContainer.mouseMove(x, y);
        this.buffsContainer.mouseMove(x, y);
    }

    mouseOut() {
        this.skillsContainer.mouseMove(99999999, 9999999);
        this.buffsContainer.mouseMove(99999999, 9999999);
    }

    onCardActive(card) {
        this.activeCard = card;
        this.__loadCardInfo(card);
    }

    onCardInactive(card) {
        if (this.activeCard == card) {
            this.activeCard = null;
        }
        if (!this.activeCard && !this.selectedCard) {
            this.skillsContainer.removeAllComponents();
        } else {
            this.__loadCardInfo(this.activeCard || this.selectedCard);
        }
    }

    onCardSelect(card) {
        this.selectedCard = card;
        this.__loadCardInfo(card);
    }

    onComponentRemoved(sender, o) {
        if (o == this.activeCard) this.activeCard = null;
        if (o == this.selectedCard) this.selectedCard = null;
    }

    __loadCardInfo(card) {
        this.__loadSkills(card);
        this.__loadBuffs(card);
    }

    __loadSkills(card) {
        this.skillsContainer.removeAllComponents();
        let index = 0;
        for (let skill of card.desc.skills) {
            this.skillsContainer.addComponent(new Skill(card, skill, index));
            ++index;
        }
    }

    __loadBuffs(card) {
        this.buffsContainer.removeAllComponents();
        let index = 0;
        for (let b of card.info.buff) {
            this.buffsContainer.addComponent(new Buff(card, b, index));
            ++index;
        }
    }

    __canShow(card) {
        // TODO
        return true;
    }

    draw(canvas) {
        let ctx = canvas.getContext('2d');
        ctx.rect(this.x, this.y, this.width, this.height);
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'rgba(192, 192, 192, 0.7)';
        ctx.fill();

        ctx.beginPath();
        let cardWidth = configuration.get('components.card.full.width');
        let cardHeight = configuration.get('components.card.full.height');
        let barPaddingTop = configuration.get('components.leftSideBar.paddingTop');
        let paddingLeft = (this.width - cardWidth) / 2;
        let cardPicX = this.x + paddingLeft;
        let cardPicY = this.y + barPaddingTop;
        let card = this.activeCard || this.selectedCard;
        if (card && this.__canShow(card) && card.front) {
            // draw frame
            let anglePixels = configuration.get('components.leftSideBar.frame.anglePixels');
            ctx.beginPath();
            ctx.moveTo(cardPicX, cardPicY + anglePixels);
            ctx.lineTo(cardPicX, cardPicY + cardHeight - anglePixels);
            ctx.lineTo(cardPicX + anglePixels, cardPicY + cardHeight);
            ctx.lineTo(cardPicX + cardWidth - anglePixels, cardPicY + cardHeight);
            ctx.lineTo(cardPicX + cardWidth, cardPicY + cardHeight - anglePixels);
            ctx.lineTo(cardPicX + cardWidth, cardPicY + anglePixels);
            ctx.lineTo(cardPicX + cardWidth - anglePixels, cardPicY);
            ctx.lineTo(cardPicX + anglePixels, cardPicY);
            ctx.closePath();
            ctx.strokeStyle = '#333333';
            ctx.lineWidth = 5;
            ctx.stroke();
            ctx.strokeStyle = '#8e8e8e';
            ctx.lineWidth = 3;
            ctx.stroke();
            ctx.strokeStyle = '#c4c4c4';
            ctx.lineWidth = 2;
            ctx.stroke();
            ctx.clip();
            ctx.drawImage(card.front, cardPicX, cardPicY, cardWidth, cardHeight);
            ctx.beginPath();
        } else {
            ctx.strokeStyle = 'white';
            ctx.rect(this.x + paddingLeft, this.y + barPaddingTop, cardWidth, cardHeight);
            ctx.stroke();
            if (this.back) {
                ctx.drawImage(this.back,
                    cardPicX, cardPicY, cardWidth, cardHeight);
            } else {
                ctx.fillStyle = '#999999';
                ctx.fill();
            }
        }

        if (!card) return;

        // hp attack defend
        let padding = configuration.get('components.leftSideBar.property.padding');
        if (card.desc.hp || card.desc.attack || card.desc.defend) {
            let lineHeight = configuration.get('components.leftSideBar.property.height');
            // draw property board
            ctx.beginPath();
            ctx.fillStyle = 'rgba(0,0,0,0.6)';
            ctx.rect(cardPicX, cardPicY + cardHeight - lineHeight * 3,
                cardWidth, lineHeight * 3);
            ctx.fill();
            ctx.beginPath();
            ctx.strokeStyle = 'white';
            ctx.lineWidth = 0.5;
            ctx.moveTo(cardPicX, cardPicY + cardHeight - lineHeight * 2);
            ctx.lineTo(cardPicX + cardWidth, cardPicY + cardHeight - lineHeight * 2);
            ctx.moveTo(cardPicX, cardPicY + cardHeight - lineHeight);
            ctx.lineTo(cardPicX + cardWidth, cardPicY + cardHeight - lineHeight);
            ctx.stroke();

            // hp atk def
            ctx.save();
            ctx.font = configuration.get('components.leftSideBar.property.font');
            ctx.fillStyle = 'white';
            ctx.textBaseline = 'top';
            let labelColor = '#a99d75';
            let valueColor = 'white';
            // hp
            ctx.textAlign = 'left';
            ctx.fillStyle = labelColor;
            ctx.fillText('HP', cardPicX + padding, cardPicY + cardHeight - lineHeight * 3);
            ctx.textAlign = 'right';
            ctx.fillStyle = valueColor;
            ctx.fillText('' + card.desc.hp, cardPicX + cardWidth - padding,
                cardPicY + cardHeight - lineHeight * 3);
            // atk
            ctx.textAlign = 'left';
            ctx.fillStyle = labelColor;
            ctx.fillText('ATK', cardPicX + padding, cardPicY + cardHeight - lineHeight * 2);
            ctx.textAlign = 'right';
            ctx.fillStyle = valueColor;
            ctx.fillText('' + card.desc.attack, cardPicX + cardWidth - padding,
                cardPicY + cardHeight - lineHeight * 2);
            // def
            ctx.textAlign = 'left';
            ctx.fillStyle = labelColor;
            ctx.fillText('DEF', cardPicX + padding, cardPicY + cardHeight - lineHeight);
            ctx.textAlign = 'right';
            ctx.fillStyle = valueColor;
            ctx.fillText('' + card.desc.defend, cardPicX + cardWidth - padding,
                cardPicY + cardHeight - lineHeight);

            ctx.restore();
        }

        // star
        let stars = card.desc.stars;
        let positions = [];
        let starWidth = configuration.get('components.leftSideBar.star.width');
        let starMargin = configuration.get('components.leftSideBar.star.margin');
        if (stars % 2 === 0) {
            let mostLeftX = cardPicX + cardWidth / 2 - starMargin / 2 - (stars / 2 - 1) * starMargin - starWidth * stars / 2;
            for (let i = 0; i < stars; ++i) {
                positions.push({x: mostLeftX, y: cardPicY + starMargin});
                mostLeftX += starWidth + starMargin;
            }
        } else {
            let mostLeftX = cardPicX + cardWidth / 2 - starWidth / 2 - (stars - 1) / 2 * (starMargin + starWidth);
            for (let i = 0; i < stars; ++i) {
                positions.push({x: mostLeftX, y: cardPicY + starMargin});
                mostLeftX += starWidth + starMargin;
            }
        }

        for (let pos of positions) {
            if (this.starImage) {
                ctx.drawImage(this.starImage, pos.x, pos.y, starWidth, starWidth);
            }
        }

        ctx.restore();
        ctx.beginPath();

        let fontSize = configuration.get('components.leftSideBar.text.fontSize');
        let fontFamily = configuration.get('components.leftSideBar.text.fontFamily');
        let textMargin = configuration.get('components.leftSideBar.text.margin');
        let twh = new utils.TextWriterHelper(ctx,
            this.x + textMargin, cardPicY + cardHeight + 30, this.width - textMargin * 2,
            fontSize, fontFamily);

        twh.writeLine('');

        twh.writeLine(card.desc.name);
        if (card.desc.properties.length > 0) {
            let tmp = card.desc.properties.map(x => configuration.get('card.properties.' + x));
            twh.writeLine("[" + tmp.join("·") + "]");
        }
        twh.writeLine(card.desc.desc);

        this.skillsContainer.draw(canvas);
        this.buffsContainer.draw(canvas);
    }
}

module.exports = LeftSideBar;
